#include "date.h"

const char * Date::_weeks[7] = {
    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};

const char * Date::_months[12] = {
    "Jan" , "Feb" , "Mar" , "Apr" , 
    "May" , "Jun" , "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec"
};

const int Date::_days_per_month[12] = {
    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30
};

Date::Date ()
{
    time_t result = time (NULL);
    struct tm *ret_tm = localtime (&result);
    _day = ret_tm->tm_mday;
    _month = ret_tm->tm_mon + 1;
    _year = ret_tm->tm_year + 1900;   
}

Date::Date (int yday, int year)
{
    int day = 1; 
    int month = 1;
    int count = 0;
    int feb;
    if (is_leap_year (year))
        feb = 29;
    else
        feb = 28;

    while (count != yday)
    {
        int days = _days_per_month[month-1];
        if (month == 2) days = feb;
        if (day > days)
        {
            day = 1;
            month++;
        }
        day++;
        count++;
    }

    setDate (day - 1, month, year);
}

Date::Date (int day, int month, int year)
{
    setDate (day, month, year);
}

Date::Date (string month, int day, int year)
{
    int i = 0;
    while (month != _months[i++])
        ;
    setDate (day, i, year);
}

Date::~Date ()
{
    cout << "Date object destructor for date ";
    print ();
}

Date & Date::setDay (int day)
{
    setDate (day, -1, -1);
    return *this;
}

Date & Date::setMonth (int month)
{
    setDate (-1, month, -1);
    return *this;
}

Date & Date::setYear (int year)
{
    setDate (-1, -1, year);
    return *this;
}

Date & Date::setDate (int day, int month, int year)
{
    if (year != -1)
        _year = year > 0 ? year : 1900;
    if (month != -1)
        _month = 0 < month && month < 13 ? month : 1;
    if (day != -1)
        _day = 0 < day && day <= _days_per_month[_month-1] ? day : 1;
    
    return *this;
}

int Date::getDay () const
{
    return _day;
}

int Date::getMonth () const
{
    return _month;
}

int Date::getYear () const
{
    return _year;
}

int Date::getDayOfYear () const
{
    struct tm tmp_tm;

    tmp_tm.tm_mday = getDay ();
    tmp_tm.tm_mon  = getMonth () - 1;
    tmp_tm.tm_year = getYear () - 1900;
    tmp_tm.tm_sec = 0;
    tmp_tm.tm_min = 0;
    tmp_tm.tm_hour = 0;

    mktime (&tmp_tm);

    return tmp_tm.tm_yday + 1;
}

const char * Date::getMonthName () const
{
    return _months[_month - 1];
}

void Date::print () const
{
    cout << getMonth () << "/" << getDay () << "/" << getYear ();
    cout << endl;
}

void Date::printDDDYYYY () const
{
    cout << getDayOfYear () << " " << getYear ();
    cout << endl;
}

void Date::printMMDDYY () const
{
    ios::fmtflags oldFlags = cout.flags ();

    cout.fill ('0');
    cout << setw (2) << getMonth ()  << "/"
         << setw (2) << getDay () << "/";
    int tmp = getYear ();
    cout << (tmp / 10) % 10;
    cout << tmp % 10;
    cout << endl;

    cout.flags (oldFlags);
}

void Date::pirntMonthDDYYYY () const
{
    cout << getMonthName () << " " 
         << getDay () << ", " << getYear ();
    cout << endl;
}

bool Date::is_leap_year (int year)
{
    if ((year%4 == 0 && year%100 != 0) || year%400 == 0)
        return true;
    else
        return false;
}
